home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part1 / 7982 < prev    next >
Encoding:
Text File  |  1996-08-05  |  2.4 KB  |  94 lines

  1. Path: natinst.com!usenet
  2. From: "Jonathan S. Brumley" <brumley@natinst.com>
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: Virtual Constructors (how to implement)?
  5. Date: Fri, 16 Feb 1996 13:48:15 -0600
  6. Organization: National Instruments
  7. Message-ID: <3124DF7F.2766@natinst.com>
  8. References: <4g0lle$nmq@jobe.shell.portal.com>
  9. NNTP-Posting-Host: rosemary.natinst.com
  10. Mime-Version: 1.0
  11. Content-Type: text/plain; charset=us-ascii
  12. Content-Transfer-Encoding: 7bit
  13. X-Mailer: Mozilla 2.0 (Win95; I)
  14.  
  15. Clare Chu wrote:
  16. > I have an abstract base class Packet.  Inherited from Packet
  17. > are specific packets like LoginPacket, AuditPacket, etc.
  18. > What I need is to read a socket (stream), and then construct
  19. > the packet of the right kind, depending on what it is.
  20. > I read a reference to this technique in Scott Meyer's More Effective C++
  21. > but I haven't received my copy yet.  (It is back-ordered at Computer
  22. > Literacy).
  23. > I need someone to basically outline what I need to do to set
  24. > up such a function that reads from a stream, produces the appropriate
  25. > object and returns a pointer to Packet pointing to the object
  26. > which is of the appropriate derived class.
  27. > At present, I'm trying to implement it as an array of pointers
  28. > to functions.  Those functions will be called based on the
  29. > Packet type, and create the appropriate object.  Of course I
  30. > haven't even thought about going out of scope, destructors,
  31. > or such.  My coworker says to just use a big switch statement
  32. > and construct objects based on the type.
  33. > Any ideas?
  34. > Thanks in advance,
  35. > Clare
  36. > clare@shell.portal.com
  37.  
  38. One way to do this is to create 
  39.  
  40.   virtual Packet* Clone() = 0;
  41. and
  42.   virtual void Restore(istream& in) = 0;
  43.  
  44. method in your packet class. In each of your derived classes,
  45. define clone() to return a new clone of the appropriate type,
  46. and Restore to read in the data based on the stream.
  47.  
  48. e.g.
  49.  
  50.   Packet* LoginPacket::Clone() 
  51.   { 
  52.     return new LoginPacket(); 
  53.   }
  54.  
  55.   void LoginPacket::Restore(istream& in)
  56.   {
  57.     in >> packetSize;
  58.     // ... etc
  59.   }
  60.  
  61. At initialization time, put a prototype of each class in a table,
  62. so that it can be found based on type.
  63.  
  64. class PacketFactory
  65. {
  66.   Packet* table[number_of_types];
  67.   ...
  68. };
  69.  
  70. PacketFactory::PacketFactory()
  71. {
  72.   table[LoginType] = new LoginPacket;
  73.   table[AuditType] = new AuditType;
  74.   ...
  75. }
  76.  
  77. to read in the class, 
  78.  
  79. Packet* Factory::Restore(istream& in)
  80. {
  81.   int type;
  82.   in >> type;
  83.   
  84.   Packet* recovered = table[type]->Clone();
  85.   recovered->Restore(in);
  86. }
  87.